package jinyilw.common;

import jinyilw.common.log.LogTools;

import java.util.Locale;

public class JvmTools
{
	private static Double javaVersion;
	private static Double javaRuntimeVersion = getJavaRuntimeVersion();

	static
	{
		LogTools.info("Runtime.version: " + javaRuntimeVersion);
	}

	private JvmTools()
	{
	}

	public static double getJavaVersion()
	{
		if (javaVersion == null)
			javaVersion = toDoubleVersion(System.getProperty("java.version"));
		return javaVersion;
	}

	public static Double getJavaRuntimeVersion()
	{
		if (javaRuntimeVersion == null)
			javaRuntimeVersion = toDoubleVersion(
					System.getProperty("java.runtime.version"));
		return javaRuntimeVersion;
	}

	public static Double toDoubleVersion(String version)
	{
		return toDoubleVersion(version, 1.3);
	}

	public static double toDoubleVersion(String version, double defaultVersion)
	{
		if (version == null)
			return defaultVersion;
		try
		{
			StringBuilder dVer = new StringBuilder();
			boolean firstPoint = true;
			for (int i = 0; i < version.length(); i++)
			{
				char ch = version.charAt(i);
				if (ch == '.' || ch == '+')
				{
					if (firstPoint)
						dVer.append('.');
					firstPoint = false;
				} else if (Character.isDigit(ch))
					dVer.append(ch);
			}
			return Double.parseDouble(dVer.toString());
		} catch (NumberFormatException e)
		{
			e.printStackTrace();
			return defaultVersion;
		}
	}

	public static double compareVersions(String version1, String version2)
	{
		return toDoubleVersion(version1) - toDoubleVersion(version2);
	}

	public static boolean isJavaVersionAtLeast(String v)
	{
		return getJavaRuntimeVersion() >= toDoubleVersion(v);
	}

	public static boolean isJavaVersionAtLeast(double v)
	{
		return getJavaRuntimeVersion() >= v;
	}

	public static boolean isJavaVersionGreaterOrEqual(String javaMinimumVersion)
	{
		return toDoubleVersion(javaMinimumVersion) <= getJavaVersion();
	}

	public static boolean isJavaVersionBetween(String javaMinimumVersion,
			String javaMaximumVersion)
	{
		getJavaVersion();
		return toDoubleVersion(javaMinimumVersion) <= javaVersion
				&& toDoubleVersion(javaMaximumVersion) > javaVersion;
	}

	public static boolean isOracleJvm()
	{
		return JvmType.isOracleJvm;
	}

	public static boolean isSunJvm()
	{
		return JvmType.isSunJvm;
	}

	public static boolean isAppleJvm()
	{
		return JvmType.isAppleJvm;
	}

	public static boolean isJetbrainsJvm()
	{
		return JvmType.isJetbrainsJvm;
	}

	/**
	 * 获得Jvm类型的枚举类
	 */
	public enum JvmType
	{
		AppleJvm, OracleJvm, SunJvm, JetbrainsJvm, Other;

		private static JvmType jvmType;

		public static JvmType getJvmType()
		{
			if (jvmType == null)
			{
				String vmName = System.getProperty("java.vm.vendor");
				if (vmName == null)
					return null;
				vmName = vmName.toLowerCase(Locale.ENGLISH);
				jvmType = vmName.contains("sun")
						&& vmName.contains("microsystems")
						? SunJvm
						: vmName.contains("apple")
						? AppleJvm
						: vmName.contains("oracle")
						? OracleJvm
						: vmName.contains("jetbrains")
						? JetbrainsJvm
						: Other;
			}
			return jvmType;
		}

		public static final boolean isAppleJvm = getJvmType() == AppleJvm;
		public static final boolean isSunJvm = getJvmType() == SunJvm;
		public static final boolean isOracleJvm = getJvmType() == OracleJvm;
		public static final boolean isJetbrainsJvm = getJvmType() == JetbrainsJvm;
	}
}
